module executor.initialization.client.InitExecutor;

import msgtrans;
import message.Constants;
import cache.UserStatusManager;
import hunt.logging;
import google.protobuf;
import message.MsgDefine;
import cache.ChatIdMap;
import client.GateServerClient;
import client.MsgServerClient;
import std.array;
import std.conv : to;
import client.LogicServerClient;

/**
 * 启动时的初始化操作
 * 
 * 初始化ChatIdMap和UserStatusManager
 * 
 */
@TransportClient(LogicClientName)
class InitExecutor : AbstractExecutor!(InitExecutor){

  @MessageId(MESSAGE.CMD_CHATMAP)
  void initChatMap(TransportContext ctx, MessageBuffer buffer) //初始化动作，当连接上logicServer之后 logice会推送chatId关系列表给msgserver
  {
    ChatMap mp = new ChatMap;
    buffer.data.fromProtobuf!ChatMap(mp);
    foreach(GroupInfo member; mp.map)
    {
      int chatId = member.groupId;
      string[string] users;
      foreach(int userId ; member.memberId)
      {
        users[to!string(userId)] = to!string(userId);
      }
      ChatIdMap.getInstance().createChat(to!string(chatId),users);
      logInfo("initChatMap ----- %s",  chatId);
    }

    foreach(int id ; mp.onlineMember)
    {
        //UserStatusManager.getInstance().setUserStatus(to!string(id),true);
    }

  }

   @MessageId(MESSAGE.CMD_SET_GROUP_NAME_REQ)
   void setName(TransportContext ctx, MessageBuffer buffer)
   {
     SetGroupNameREQ req = new SetGroupNameREQ;
     buffer.data.fromProtobuf!SetGroupNameREQ( req);
     string[string] chatMap = ChatIdMap.getInstance().getGroupInfo( req.groupId);

     auto res = new SetGroupNameRES;
     res.groupId = req.groupId;
     res.groupName = req.groupName;
     res.succeeded = true;

     foreach (string clientId ; chatMap)
     {
       res.userId = clientId;

       MessageTransportClient client = MsgServerClient.getInstance.getForwardClient(clientId);
       if (client is null) //hash到本机
       {
         logInfo( "clientId local: %s",clientId);
         if (UserStatusManager.getInstance().getUserStatus(clientId))
         {
           TransportSession[ulong] contexts = GateServerClient.getInstance.getAllClient();
           foreach (TransportSession c ; contexts)
           {
             c.send( new MessageBuffer( MESSAGE.CMD_SET_GROUP_NAME_RES,res.toProtobuf.array));
           }
         }
       }else
       {
         logInfo( "clientId other server: %s",clientId);
         client.send( new MessageBuffer(MESSAGE.CMD_SET_GROUP_NAME_HASH_RES,res.toProtobuf.array));
       }
     }
   }

  @MessageId(MESSAGE.CMD_CHAT_MAP_ACTION)
  void chatMapAction(TransportContext ctx, MessageBuffer buffer) //chatId关系列表同步接口
  {
    ChatMapAction action = new ChatMapAction;
    buffer.data.fromProtobuf!ChatMapAction(action);
    string[string] strMember;
    switch (action.type)
    {
      case ChatMapActionType.CREATE: //新创建
      {
        string[string] users;
        foreach(string m ; action.member)
        {
          users[m] = m;
        }
        ChatIdMap.getInstance().createChat(action.chatId, users);
        updateGroupList(action.chatId,users,action);
        break;
      }
      case ChatMapActionType.ADD: //添加
      {
        foreach(string m ; action.member)
        {
          ChatIdMap.getInstance().addMember(action.chatId, m);
          strMember[m] = m;
        }
        updateGroupList(action.chatId, strMember, action);
        break;
      }
      case ChatMapActionType.KICK: //踢出
          goto case;
      case ChatMapActionType.DELETE: //删除
      {

        foreach(string m ; action.member)
        {
          ChatIdMap.getInstance().deleMember(action.chatId, m);
          strMember[m] = m;
        }
        updateGroupList(action.chatId, strMember, action);
        break;
      }
      case ChatMapActionType.DESTROY:
      {
        ChatIdMap.getInstance().deleChat(action.chatId);
       // updateGroupList(action.chatId, strMember, action);
        break;
      }
      default:
        break;
    }
    logInfof("chatMapAction ----- %d ----%s",action.type ,action.chatId);
  }
}

void updateGroupList(string chatId, string[string] newMember , ChatMapAction action)
{
  string[string] chatMap =  ChatIdMap.getInstance().getGroupInfo(chatId);
  if(chatMap.length == 0)
  {
      ChatIdMap.getInstance().deleChat(chatId);
  }
  foreach(string clientId ; chatMap)
  {
    //if (clientId in newMember)
    //{
    //  continue;
    //}
    action.destination = clientId;

    MessageTransportClient client = MsgServerClient.getInstance.getForwardClient(clientId);
    if (client is null) //hash到本机
    {
      logInfo("clientId local: %s",clientId );
      if (UserStatusManager.getInstance().getUserStatus(clientId))
      {
        TransportSession[ulong] contexts = GateServerClient.getInstance.getAllClient();
        foreach(TransportSession c ; contexts)
        {
          logInfo("updateGroupList  %s  ----  %s ---- %d" ,  clientId , chatId , action.type);
          c.send(new MessageBuffer(MESSAGE.CMD_GROUP_MEMBER_CHANGE,action.toProtobuf.array));
        }
      }else
      {
        if (action.type == ChatMapActionType.ADD || action.type == ChatMapActionType.CREATE)
        {
          if(action.member.length == 1 && action.manager == action.member[0])
          {
              return;
          }
          MessageTransportClient logicClient = LogicServerClient.getInstance().getForwardClient();
          string[] arr;

          foreach (string m; action.member)
          {
              if(m != action.manager)
              {
                  arr ~= m;
              }
          }
          //foreach(string m ; action.member)
          //{
          auto msg = new Msg;
          msg.chatId = chatId;
          msg.fromUserId = action.manager;
          msg.message = arr.join(",");
          msg.msgTime = action.timestamp;
          if(action.type == ChatMapActionType.CREATE && action.member.length == 2)
          {
            msg.type = MsgType.NOTICE_CONTACTS_ADD;
          }else
          {
            msg.type = MsgType.NOTICE_GROUP_ADD;
          }

          msg.localId = clientId;
          logicClient.send(new MessageBuffer(MESSAGE.CMD_PUT_UNRECEIVE,msg.toProtobuf.array));
          //}
        }
      }
    }else
    {
      logInfo("clientId other server: %s",clientId );
      client.send(new MessageBuffer(MESSAGE.CMD_GROUP_MEMBER_CHANGE_HASH,action.toProtobuf.array));
    }
  }
}
